package mysql

/*
 * mysql proxy wrapper, which is thread safe.
 */
import (
	"fmt"
	"sync"
)

// /////////////////////////////////////////////////////
// 连接数据库的各种logic id.
const (
	// invalid logic id.
	InvalidLogicId = iota

	// Role module logic id.
	RoleModuleLogicId
)

///////////////////////////////////////////////////////////////////////////////

type mysqlProxy struct {
	proxyMap sync.Map
}

// CreateMysqlProxy creates new mysql client with db config
func (proxy *mysqlProxy) CreateMysqlProxy(logicId uint32, conf *DBConf) (*MysqlClient, error) {
	if v, ok := proxy.proxyMap.Load(logicId); ok {
		return v.(*MysqlClient), fmt.Errorf("find %d repeated", logicId)
	}

	mysqlClient := NewMysqlClient(conf)
	if err := mysqlClient.Connect(); err != nil {
		return nil, err
	} else {
		proxy.proxyMap.Store(logicId, mysqlClient)
		return mysqlClient, nil
	}
}
func (proxy *mysqlProxy) CreateClusterMysqlProxy(logicId uint32, conf *DBConf) (*MysqlClient, error) {
	if v, ok := proxy.proxyMap.Load(logicId); ok {
		return v.(*MysqlClient), fmt.Errorf("find %d repeated", logicId)
	}

	mysqlClient := NewMysqlClient(conf)
	if err := mysqlClient.ConnectCluster(); err != nil {
		return nil, err
	} else {
		proxy.proxyMap.Store(logicId, mysqlClient)
		return mysqlClient, nil
	}
}

// mysql proxy.
func (proxy *mysqlProxy) GetMysqlProxy(logicId uint32) MysqlExecutorProxy {
	if v, ok := proxy.proxyMap.Load(logicId); ok {
		return v.(*MysqlClient)
	} else {
		return nil
	}
}

// mysql proxy with Tx.
func (proxy *mysqlProxy) GetMysqlProxyWithTx(logicId uint32) (MysqlExecutorProxy, error) {
	if v, ok := proxy.proxyMap.Load(logicId); ok {
		return v.(*MysqlClient).CreateTx()
	} else {
		return nil, fmt.Errorf("can not find %d tx", logicId)
	}
}

// ReleaseMysqlProxy releases mysql proxy with logicId.
func (proxy *mysqlProxy) ReleaseMysqlProxy(logicId uint32) {
	if v, ok := proxy.proxyMap.Load(logicId); ok {
		if client := v.(*MysqlClient); client != nil {
			client.Close()
		}
		proxy.proxyMap.Delete(logicId)
	}
}

// global mysql proxy.
var MysqlProxyObj mysqlProxy
